// Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef _CLIENT_COMMON_H_
#define _CLIENT_COMMON_H_

#include <string.h>
#include <stdio.h>
#include <libgen.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <libgen.h>
#include <unistd.h>
#include <map>
#include <vector>
#include <cstring>

#define SOCKET_HEARTBEAT 0x0001

#define SOCKET_WORKER_STATUS_REQ 0x0203 // worker状态查询请求,并下发UUID信息
#define SOCKET_WORKER_STATUS_REPORT 0x0204 // worker状态应答以及主动上报

#define IP_ADDR_LENGTH 16
#define UUID_LENGTH 40
#define INVALID_UUID "invalid_uuid"

typedef enum {
    SOCKET_PATTERN_NOBLOCK = 0x0,
    SOCKET_PATTERN_BLOCK = 0x1
} PatternType;

typedef enum {
    ENCODE_POOL_CPU = 0x1,
    ENCODE_POOL_GPU = 0x2
} EncodePoolEncodeType;

typedef enum {
    ENCODE_POOL_ENCODE = 0x0,
    ENCODE_POOL_DECODE = 0x1
} EncodePoolResourceType;

typedef enum {
    ENCODE_POOL_H264 = 0x0,
    ENCODE_POOL_H265 = 0x1,
    ENCODE_POOL_MIX = 0x2,
} EncodePoolDataType;

typedef enum {
    ENCODE_POOL_720P = 0x0,
    ENCODE_POOL_1080P = 0x1
} EncodePoolResolution;

typedef enum {
    ENCODE_POOL_WORKER_IDLE = 0x0,
    ENCODE_POOL_WORKER_BUSY = 0x2
} EncodePoolWorkerStatus;

typedef struct HeartbeatParamS {
    uint32_t timestamp;
    uint32_t heartIndex;
} __attribute__((packed)) HeartbeatParamT;

/** 0x0204 worker状态上报 */
struct RemoteWorkerStatusReq {
    char workerUuid[UUID_LENGTH];
    char workerIp[IP_ADDR_LENGTH];
    uint32_t port;
    uint32_t status; // worker实例的状态
    uint8_t encodeType;
    uint8_t resourceType;
    uint8_t dataType;
    uint8_t flavorType;
    uint8_t frameRate;
} __attribute__((packed));

static constexpr uint32_t REMOTE_WORKER_STATUS_REQ_SIZE = sizeof(RemoteWorkerStatusReq);

/** 对外接口,提供给用户回调的API类型 */
typedef void *(*callbackClientRead)(uint16_t cmdCtl, uint8_t *pOutData, uint32_t outLen);

typedef struct ReadParamsS {
    callbackClientRead callBackFunc;
    void *params;
} ReadParamsT;

extern ReadParamsT gReadParams;

/** 注册回调socket读命令 */
void socketClientRegCallbackRead(callbackClientRead pParam1, void *pParam2);

class CommonClientPublic {

public:

    CommonClientPublic();

    ~CommonClientPublic();

public:
    int connectMasterInit(std::string configFileName, uint32_t port, const std::string& encodeType,
                          const std::string& videoFrameType, const std::string& resolution, const std::string& fps);
    int reportStatus(uint32_t status);
    int reportHeartbeat();

private:
    int sendCmdData(uint16_t cmdCtl, uint8_t *inData, uint32_t inLen);
};

extern CommonClientPublic gClientInfo;

#endif